/*
***************************************************************************************************
*   LTC2440.c
*   LTC2440 驱动文件，将SDI接地，使用21位精度模式。读出数据时，由外部时钟激励。
*
***************************************************************************************************
*/

#include "main.h"       // 提供引脚宏定义
#include "LTC2440.h"    // 提供LTC2440返回的数据结构定义

static void naive_delay_us(uint16_t nus)
{
    uint32_t i,j;
    uint8_t nothing;
    nothing  = 0;
    for(i = 0; i < nus; i++)
    {
        for(j = 0; j < ((uint32_t)(1)); j++)
        {
                nothing ++ ;
        }
    }
}

static inline
void reset_sck(void)
{
    HAL_GPIO_WritePin(HAND_LTC2440_SCK_GPIO_Port,HAND_LTC2440_SCK_Pin,GPIO_PIN_RESET);
}

static inline
void set_sck(void)
{
    HAL_GPIO_WritePin(HAND_LTC2440_SCK_GPIO_Port,HAND_LTC2440_SCK_Pin,GPIO_PIN_SET);
}

static inline
void set_cs(void)
{
    HAL_GPIO_WritePin(HAND_LTC2440_CS_GPIO_Port,HAND_LTC2440_CS_Pin,GPIO_PIN_SET);
}

static inline
void reset_cs(void)
{
    HAL_GPIO_WritePin(HAND_LTC2440_CS_GPIO_Port,HAND_LTC2440_CS_Pin,GPIO_PIN_RESET);
}

static inline
void delay_moment(void)
{
    naive_delay_us(20);
}

// static inline
// void delay_shorter_moment(void)
// {
//     naive_delay_us(2);
// }

static inline 
uint8_t read_MISO_pin(void)
{
    return (uint8_t)(HAL_GPIO_ReadPin(HAND_LTC2440_MISO_GPIO_Port,HAND_LTC2440_MISO_Pin));
}

static LTC2440_rec_data_s LTC2440_data; // 从LTC2440读取到的数据
static uint8_t error = 0;

/****************************************************************************
函数名	： read_LTC2440_voltage
功能	： 从LTC2440读取电压值
参数	： 无
返回值	： voltage 读取到的电压，取值为0~5V
****************************************************************************/
float read_LTC2440_voltage (void)
{
    uint32_t data_buf,enter_time;
    uint8_t i;
    float voltage;

    enter_time = HAL_GetTick();
    reset_sck();
    reset_cs();
    error = 0;
    // 当读取SDO端口读出1时，说明转换没有完成，需要等待，直到读出0
    while(read_MISO_pin())
    {
        // 1000ms 没有转换完成，说明出现了错误。跳出，避免死循环
        if(HAL_GetTick()-enter_time > 1000)
        {
            error = 1;  // 发生了错误，返回5V电压
            return 5.0;
        }
    }

    data_buf = 0;
    for(i = 0; i < 32; i++)
    {
        data_buf <<= 1;
        set_sck();
        delay_moment();
        data_buf |= read_MISO_pin();
        reset_sck();
        delay_moment();
    }
    set_cs();
    LTC2440_data = *((LTC2440_rec_data_s * )&data_buf);
    voltage = (double)5.0 * (double)LTC2440_data.basic_data / 0xFFFFFF;  //24位ADC读取的值
    return voltage;
}

/****************************************************************************
函数名	： LTC2440_is_error
功能	： 从LTC2440读取错误情况
参数	： 无
返回值	： error - 为1表示发生了一次卡住的错误，为0表示没有发生卡住的错误
****************************************************************************/
uint8_t LTC2440_is_error(void)
{
    return error;
}
